package com.yhh.college_information_platform.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yhh.college_information_platform.common.PageResult;
import com.yhh.college_information_platform.dto.SearchDTO;
import com.yhh.college_information_platform.entity.Resource;
import com.yhh.college_information_platform.entity.SearchHistory;
import com.yhh.college_information_platform.mapper.ResourceMapper;
import com.yhh.college_information_platform.mapper.SearchHistoryMapper;
import com.yhh.college_information_platform.service.SearchService;
import com.yhh.college_information_platform.vo.ResourceVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 搜索Service实现类
 *
 * @author yhh
 * @date 2025-10-26
 */
@Slf4j
@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private SearchHistoryMapper searchHistoryMapper;

    @Override
    public PageResult<ResourceVO> searchResources(SearchDTO searchDTO, Long userId) {
        String keyword = searchDTO.getKeyword();
        
        // 构建查询条件
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        
        // 只查询已审核通过的资料
        wrapper.eq(Resource::getStatus, 1);
        
        // 关键词搜索（标题、描述、文件名）
        if (StrUtil.isNotBlank(keyword)) {
            wrapper.and(w -> w
                .like(Resource::getTitle, keyword)
                .or()
                .like(Resource::getDescription, keyword)
                .or()
                .like(Resource::getFileName, keyword)
            );
        }
        
        // 分类筛选
        if (searchDTO.getCategoryId() != null) {
            wrapper.eq(Resource::getCategoryId, searchDTO.getCategoryId());
        }
        
        // 排序
        Integer sortType = searchDTO.getSortType();
        if (sortType == null) {
            sortType = 0;
        }
        
        switch (sortType) {
            case 1: // 最新
                wrapper.orderByDesc(Resource::getCreateTime);
                break;
            case 2: // 下载量
                wrapper.orderByDesc(Resource::getDownloadCount);
                break;
            case 3: // 浏览量
                wrapper.orderByDesc(Resource::getViewCount);
                break;
            default: // 综合排序（下载量 + 浏览量 + 点赞数）
                wrapper.orderByDesc(Resource::getDownloadCount)
                       .orderByDesc(Resource::getViewCount)
                       .orderByDesc(Resource::getLikeCount);
                break;
        }
        
        // 分页查询
        Page<Resource> page = new Page<>(searchDTO.getCurrent(), searchDTO.getSize());
        Page<Resource> resultPage = resourceMapper.selectPage(page, wrapper);
        
        // 转换为VO
        List<ResourceVO> voList = resultPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        // 保存搜索历史
        if (userId != null && StrUtil.isNotBlank(keyword)) {
            saveSearchHistory(userId, keyword, (int) resultPage.getTotal());
        }
        
        // 构建分页结果
        PageResult<ResourceVO> pageResult = new PageResult<>();
        pageResult.setRecords(voList);
        pageResult.setTotal(resultPage.getTotal());
        pageResult.setCurrent(resultPage.getCurrent());
        pageResult.setSize(resultPage.getSize());
        pageResult.setPages(resultPage.getPages());
        
        log.info("搜索资料成功，关键词: {}, 结果数: {}", keyword, resultPage.getTotal());
        return pageResult;
    }

    @Override
    public void saveSearchHistory(Long userId, String keyword, Integer resultCount) {
        if (userId == null || StrUtil.isBlank(keyword)) {
            return;
        }
        
        // 检查是否已存在相同关键词的记录（最近的）
        LambdaQueryWrapper<SearchHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SearchHistory::getUserId, userId)
               .eq(SearchHistory::getKeyword, keyword)
               .orderByDesc(SearchHistory::getCreateTime)
               .last("LIMIT 1");
        
        SearchHistory existing = searchHistoryMapper.selectOne(wrapper);
        
        // 如果最近搜索过相同关键词（1小时内），则不重复保存
        if (existing != null && 
            existing.getCreateTime().isAfter(LocalDateTime.now().minusHours(1))) {
            return;
        }
        
        // 保存新的搜索历史
        SearchHistory history = new SearchHistory();
        history.setUserId(userId);
        history.setKeyword(keyword);
        history.setResultCount(resultCount);
        history.setCreateTime(LocalDateTime.now());
        
        searchHistoryMapper.insert(history);
        
        // 限制每个用户最多保存50条历史记录
        LambdaQueryWrapper<SearchHistory> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(SearchHistory::getUserId, userId);
        Long count = searchHistoryMapper.selectCount(countWrapper);
        
        if (count > 50) {
            // 删除最旧的记录
            LambdaQueryWrapper<SearchHistory> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(SearchHistory::getUserId, userId)
                        .orderByAsc(SearchHistory::getCreateTime)
                        .last("LIMIT " + (count - 50));
            
            List<SearchHistory> oldRecords = searchHistoryMapper.selectList(deleteWrapper);
            if (!oldRecords.isEmpty()) {
                List<Long> ids = oldRecords.stream()
                        .map(SearchHistory::getId)
                        .collect(Collectors.toList());
                searchHistoryMapper.deleteBatchIds(ids);
            }
        }
    }

    @Override
    public List<String> getUserSearchHistory(Long userId, Integer limit) {
        if (userId == null) {
            return new ArrayList<>();
        }
        
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        LambdaQueryWrapper<SearchHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SearchHistory::getUserId, userId)
               .orderByDesc(SearchHistory::getCreateTime)
               .last("LIMIT " + limit);
        
        List<SearchHistory> histories = searchHistoryMapper.selectList(wrapper);
        
        // 去重并返回关键词列表
        return histories.stream()
                .map(SearchHistory::getKeyword)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public void deleteSearchHistory(Long userId, String keyword) {
        if (userId == null) {
            return;
        }
        
        LambdaQueryWrapper<SearchHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SearchHistory::getUserId, userId);
        
        if (StrUtil.isNotBlank(keyword)) {
            // 删除指定关键词的历史
            wrapper.eq(SearchHistory::getKeyword, keyword);
        }
        
        searchHistoryMapper.delete(wrapper);
        log.info("删除搜索历史成功，用户ID: {}, 关键词: {}", userId, keyword);
    }

    @Override
    public List<String> getHotKeywords(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        // 查询最近7天的搜索记录，按关键词分组统计
        LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);
        
        // 使用原生SQL进行分组统计
        LambdaQueryWrapper<SearchHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(SearchHistory::getCreateTime, sevenDaysAgo)
               .select(SearchHistory::getKeyword)
               .groupBy(SearchHistory::getKeyword)
               .last("ORDER BY COUNT(*) DESC LIMIT " + limit);
        
        List<SearchHistory> histories = searchHistoryMapper.selectList(wrapper);
        
        return histories.stream()
                .map(SearchHistory::getKeyword)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 转换为VO
     */
    private ResourceVO convertToVO(Resource resource) {
        ResourceVO vo = new ResourceVO();
        BeanUtils.copyProperties(resource, vo);
        return vo;
    }
}

